package com.otr.ai.service;

import static org.springframework.ai.chat.client.advisor.AbstractChatMemoryAdvisor.CHAT_MEMORY_CONVERSATION_ID_KEY;
import static org.springframework.ai.chat.client.advisor.AbstractChatMemoryAdvisor.CHAT_MEMORY_RETRIEVE_SIZE_KEY;

import org.springframework.ai.chat.client.ChatClient;
import org.springframework.ai.chat.client.advisor.PromptChatMemoryAdvisor;
import org.springframework.ai.chat.client.advisor.QuestionAnswerAdvisor;
import org.springframework.ai.chat.client.advisor.SimpleLoggerAdvisor;
import org.springframework.ai.chat.memory.ChatMemory;
import org.springframework.ai.vectorstore.SearchRequest;
import org.springframework.ai.vectorstore.VectorStore;
import org.springframework.stereotype.Service;

// 静态导入ChatMemoryAdvisor中的常量，用于设置聊天记忆的参数

/**
 * 模拟的是客户支持助手，具备： 自然语言交互（ChatClient） 记忆能力（ChatMemory） 知识检索（RAG via VectorStore） 函数调用（Function
 * Calling）
 */
@Service
public class ProductService {

  /*
   * 用于控制随机性和多样性的程度。
   * 具体来说，temperature值控制了生成文本时对每个候选词的概率分布进行平滑的程度。
   * 较高的temperature值会降低概率分布的峰值，使得更多的低概率词被选择，生成结果更加多样化；
   * 而较低的temperature值则会增强概率分布的峰值，使得高概率词更容易被选择，生成结果更加确定。
   * 值范围：[0, 2)，系统默认值0.85。不建议取值为0，无意义。
   */
  public static final double TEMPERATURE = 0.1;

  /*
   * RAG 检索出最相似的N条
   */
  private static final int TOP_K = 4;

  /*
   * 历史记录检索条数
   */
  private static final int CHAT_MEMORY_RETRIEVE_SIZE = 100;

  private final ChatClient chatClient;

  public ProductService(
      ChatClient.Builder builder, ChatMemory chatMemory, VectorStore vectorStore) {

    // 管理对话历史，确保多轮对话的连贯
    PromptChatMemoryAdvisor promptChatMemoryAdvisor = new PromptChatMemoryAdvisor(chatMemory);

    // 简单日志记录。
    SimpleLoggerAdvisor simpleLoggerAdvisor = new SimpleLoggerAdvisor();

    // RAG，基于 VectorStore 检索相关知识（如相似问题答案）
    QuestionAnswerAdvisor questionAnswerAdvisor =
        new QuestionAnswerAdvisor(
            vectorStore, SearchRequest.builder().topK(TOP_K).similarityThresholdAll().build());

    // 系统提示词
    String tips =
        """
        你是一名AI客服，你的任务是和蔼地回答用户的问题，处理客户要求的各种业务。
        """;

    this.chatClient =
        builder
            .defaultSystem(tips)
            .defaultAdvisors(simpleLoggerAdvisor, promptChatMemoryAdvisor, questionAnswerAdvisor)
            .defaultTools(new ProductTools())
            .build();
  }

  public String chat(String chatId, String message) {
    return this.chatClient
        .prompt()
        .user(message)
        .advisors(
            advisorSpec ->
                advisorSpec
                    .param(CHAT_MEMORY_CONVERSATION_ID_KEY, chatId)
                    .param(CHAT_MEMORY_RETRIEVE_SIZE_KEY, CHAT_MEMORY_RETRIEVE_SIZE))
        .call()
        .content();
  }
}
